<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * Encapsulates a Dublin Core metadata element.
 *
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */
class DMDCElement extends DMModel {

	private static $dc_fields = array(
		array(
			'name' => 'Title',
			'nick' => 'title',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'title'
		),
		array(
			'name' => 'Subject',
			'nick' => 'subjec',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'subjec'
		),
		array(
			'name' => 'Description',
			'nick' => 'descri',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'descri'
		),
		array(
			'name' => 'Creator',
			'nick' => 'creato',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 1,
			'dc' => 'creato'
		),
		array(
			'name' => 'Publisher',
			'nick' => 'publis',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 1,
			'dc' => 'publis'
		),
		array(
			'name' => 'Contributors',
			'nick' => 'contri',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'contri'
		),
		array(
			'name' => 'Date',
			'nick' => 'date',
			'type' => 'DATE',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'datea'
		),
		array(
			'name' => 'Type',
			'nick' => 'type',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'type'
		),
		array(
			'name' => 'Format',
			'nick' => 'format',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'format'
		),
		array(
			'name' => 'Identifier',
			'nick' => 'identi',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'identi'
		),
		array(
			'name' => 'Source',
			'nick' => 'source',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'identi'
		),
		array(
			'name' => 'Language',
			'nick' => 'langua',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 1,
			'vocab' => 0,
			'dc' => 'langua'
		),
		array(
			'name' => 'Relation',
			'nick' => 'relati',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'langua'
		),
		array(
			'name' => 'Coverage',
			'nick' => 'covera',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 0,
			'dc' => 'covera'
		),
		array(
			'name' => 'Rights',
			'nick' => 'rights',
			'type' => 'TEXT',
			'size' => 0,
			'search' => 1,
			'hide' => 0,
			'vocab' => 1,
			'dc' => 'rights'
		)
	);

	/** @var DMCollection */
	private $collection;
	/** @var Boolean */
	private $controlled = false, $hidden = false,
		$searchable = false, $sortable = false, $is_default_sort = false;
	/** @var string DC element nickname */
	private $dc_nick;
	/** @var int */
	private $maxwords;
	/** @var string */
	private $name;
	/** @var string CONTENTdm(R) field nickname */
	private $nick;
	/** @var string */
	private $type;
	/** @var string */
	private $value;

	/**
	 * @return array Array of DMDCElement objects corresponding to the
	 * unqualified Dublin Core Metadata Element Set (DCMES).
	 * @since 0.1
	 */
	public static function getAll() {
		$return = array();
		foreach (self::$dc_fields as $f) {
			$field = new DMDCElement($f['nick']);
			$field->setName($f['name']);
			$field->setControlled($f['vocab']);
			$field->setSearchable($f['search']);
			$field->setHidden($f['hide']);
			$field->setDCNick($f['dc']);
			$field->setType($f['type']);
			$return[] = $field;
		}
		return $return;
	}

	/**
	 * @param string nick
	 * @return string
	 */
	public static function getNameForDCNick($nick) {
		foreach (self::$dc_fields as $field) {
			if (strtolower($field['nick']) == strtolower($nick)) {
				return $field['name'];
			}
		}
		return null;
	}

	/**
	 * @param string nick CONTENTdm(R) field nickname
	 * @since 0.1
	 */
	public function __construct($nick) {
		$this->setNick($nick);
	}

	/**
	 * @return string The value of the field. Equivalent to getValue().
	 * @see getValue()
	 * @since 0.1
	 */
	public function __toString() {
		return (string) $this->getValue();
	}

	/**
	 * @return DMCollection
	 * @since 0.1
	 */
	public function getCollection() {
		return $this->collection;
	}

	/**
	 * @param DMCollection c
	 * @since 0.1
	 */
	public function setCollection(DMCollection $c) {
		$this->collection = $c;
	}

	/**
	 * @return Boolean
	 * @since 0.1
	 */
	public function isControlled() {
		return $this->controlled;
	}

	/**
	 * @param Boolean bool
	 * @since 0.1
	 */
	public function setControlled($bool) {
		$this->controlled = ($bool);
	}

	/**
	 * @return string
	 * @since 0.3
	 */
	public function getDCName() {
		return self::getNameForDCNick($this->getDCNick());
	}

	/**
	 * @return string
	 * @since 0.3
	 */
	public function getDCNick() {
		return $this->dc_nick;
	}

	/**
	 * @param string nick
	 * @since 0.3
	 */
	public function setDCNick($nick) {
		$this->dc_nick = $nick;
	}

	/**
	 * @return Boolean
	 * @since 0.1
	 */
	public function isDefaultSort() {
		return $this->is_default_sort;
	}

	/**
	 * @param Boolean bool
	 * @since 0.1
	 */
	public function setDefaultSort($bool) {
		$this->is_default_sort = ($bool);
	}

	/**
	 * @return Boolean
	 * @since 0.1
	 */
	public function isHidden() {
		return $this->hidden;
	}

	/**
	 * @param Boolean bool
	 * @since 0.1
	 */
	public function setHidden($bool) {
		$this->hidden = ($bool);
	}

	/**
	 * @return int
	 * @since 0.1
	 */
	public function getMaxWords() {
		return $this->maxwords;
	}

	/**
	 * @param int maxwords
	 * @since 0.1
	 */
	public function setMaxWords($maxwords) {
		$this->maxwords = (int) $maxwords;
	}

	/**
	 * @return string
	 * @since 0.1
	 */
	public function getName() {
		return $this->name;
	}

	/**
	 * @param string name
	 * @since 0.1
	 */
	public function setName($name) {
		$this->name = $name;
	}

	/**
	 * @return string
	 * @since 0.1
	 */
	public function getNick() {
		return $this->nick;
	}

	/**
	 * @param string nick
	 * @since 0.1
	 */
	public function setNick($nick) {
		$this->nick = $nick;
	}

	/**
	 * @return Boolean
	 * @since 0.1
	 */
	public function isSearchable() {
		return $this->searchable;
	}

	/**
	 * @return Boolean
	 * @since 0.1
	 */
	public function isSortable() {
		return $this->sortable;
	}

	/**
	 * @param Boolean bool
	 * @since 0.1
	 */
	public function setSearchable($bool) {
		$this->searchable = ($bool);
	}

	/**
	 * @param Boolean bool
	 * @since 0.1
	 */
	public function setSortable($bool) {
		$this->sortable = ($bool);
	}

	/**
	 * @return string
	 * @since 0.3
	 */
	public function getType() {
		return $this->type;
	}

	/**
	 * @param string type One of "TEXT", "FULLRES", "FTS", or "'DATE", per the
	 * dmGetCollectionFieldInfo() function
	 * @throws DMIllegalArgumentException
	 * @since 0.3
	 */
	public function setType($type) {
		if (!in_array($type, array("TEXT", "FTS", "FULLRES", "DATE"))) {
			throw new DMIllegalArgumentException("");
		}
		$this->type = $type;
	}

	/**
	 * @return string
	 * @since 0.1
	 */
	public function getValue() {
		return $this->value;
	}

	/**
	 * @param string value
	 * @since 0.1
	 */
	public function setValue($value) {
		$this->value = (string) $value;
	}

	/**
	 * This method requires association with a collection, and will not work
	 * with the default collection. Generally it should be called from a
	 * DMCollection object, like:
	 * DMCollection->getField("nick")->getVocabulary("subjec");
	 *
	 * @param Boolean dict If true, uses the CONTENTdm(R) field indices; if
	 * false, uses the controlled vocabulary.
	 * @param Boolean include_unused If true, includes terms that are not being
	 * used by any objects.
	 * @return Indexed array of strings
	 * @since 0.1
	 */
	public function getVocabulary($dict = true, $include_unused = false) {
		if ($this->getCollection()) {
			return dmGetCollectionFieldVocabulary(
				$this->getCollection()->getAlias(), $this->getNick(),
				(int) $dict, (int) $include_unused);
		}
		return array();
	}

}
